using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using UWBGL_WinForms_Lib1;
using UWBGL_XNA_Lib10;

namespace XNA_WCSupport
{
	public class Model
	{
		private UWB_XFormInfo mXForm;
		private bool mShowPivot;
		private UWB_PrimitiveList mFigure;

		private UWB_BoundingBox mWorldBounds;

		private UWB_XNADrawHelper mDrawHelper;

		private UWB_PrimitiveList redBoxList; // as a primitive_list
		private UWB_PrimitiveRectangle redBox;

		private string _hoverLoc;
		private int hwX, hwY, dvX, dvY;
		private float wdX, wdY, wdSmallX, wdSmallY, prevSmallX, prevSmallY;
		private bool _bZooming;

		const int kBodyGrayColor = 195;

		public Model()
		{
			hwX = hwY = dvX = dvY = 0; //int
			wdX = wdY = wdSmallX = wdSmallY = 0;//float
			_bZooming = false;

			redBoxList = new UWB_PrimitiveList(); // new list
			redBox = new UWB_PrimitiveRectangle();
			redBox.setFlatColor(Color.Red);
			redBox.setShadingColor(Color.Red);
			redBox.setFillMode(eFillMode.fmWireframe);
			redBox.setCorners(new Vector3(10, 10, 0), new Vector3(20, 18, 0));
			redBoxList.append(redBox);



			mShowPivot = false;
			mFigure = new UWB_PrimitiveList();
			mXForm = new UWB_XFormInfo();
			mWorldBounds = new UWB_BoundingBox();
			mDrawHelper = new UWB_XNADrawHelper();

			#region doll layout
			UWB_PrimitiveRectangle torso = new UWB_PrimitiveRectangle();
			torso.setCorners(new Vector3(15, 11, 0), new Vector3(25, 24, 0));
			torso.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			torso.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle leftLeg = new UWB_PrimitiveRectangle();
			leftLeg.setCorners(new Vector3(16, 0, 0), new Vector3(18, 11, 0));
			leftLeg.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			leftLeg.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle rightLeg = new UWB_PrimitiveRectangle();
			rightLeg.setCorners(new Vector3(22, 0, 0), new Vector3(24, 11, 0));
			rightLeg.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			rightLeg.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle leftArm = new UWB_PrimitiveRectangle();
			leftArm.setCorners(new Vector3(9, 22, 0), new Vector3(15, 24, 0));
			leftArm.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			leftArm.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle leftArm2 = new UWB_PrimitiveRectangle();
			leftArm2.setCorners(new Vector3(8, 17, 0), new Vector3(10, 24, 0));
			leftArm2.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			leftArm2.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle rightArm = new UWB_PrimitiveRectangle();
			rightArm.setCorners(new Vector3(25, 22, 0), new Vector3(31, 24, 0));
			rightArm.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			rightArm.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle rightArm2 = new UWB_PrimitiveRectangle();
			rightArm2.setCorners(new Vector3(30, 17, 0), new Vector3(32, 24, 0));
			rightArm2.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			rightArm2.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle neck = new UWB_PrimitiveRectangle();
			neck.setCorners(new Vector3(18, 24, 0), new Vector3(22, 26, 0));
			neck.setFlatColor(new Color(kBodyGrayColor, kBodyGrayColor, kBodyGrayColor));
			neck.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveCircle face = new UWB_PrimitiveCircle();
			face.setCenter(20, 30, 0);
			face.setRadius(5);
			face.setFlatColor(new Color(28, 28, 55));
			face.setShadingColor(new Color(255, 128, 192));

			UWB_PrimitiveCircle leftEye = new UWB_PrimitiveCircle();
			leftEye.setCenter(18, 32, 0);
			leftEye.setRadius(1);

			UWB_PrimitiveCircle rightEye = new UWB_PrimitiveCircle();
			rightEye.setCenter(22, 32, 0);
			rightEye.setRadius(1);

			UWB_PrimitiveRectangle nose = new UWB_PrimitiveRectangle();
			nose.setCorners(new Vector3(20 - 1, 30 - .5f, 0), new Vector3(20 + 1, 30 + .5f, 0));
			nose.setFlatColor(new Color(65, 0, 122));
			nose.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle mouth = new UWB_PrimitiveRectangle();
			mouth.setCorners(new Vector3(20 - 2.5f, 27.5f - .5f, 0), new Vector3(20 + 2.5f, 27.5f + .5f, 0));

			UWB_PrimitiveRectangle topTooth = new UWB_PrimitiveRectangle();
			topTooth.setCorners(new Vector3(21.25f - .25f, 27.75f - .25f, 0), new Vector3(21.25f + .25f, 27.75f + .25f, 0));
			topTooth.setFlatColor(new Color(200, 200, 200));
			topTooth.setShadeMode(eShadeMode.smFlat);

			UWB_PrimitiveRectangle btmTooth = new UWB_PrimitiveRectangle();
			btmTooth.setCorners(new Vector3(19.25f - .25f, 27.25f - .25f, 0), new Vector3(19.25f + .25f, 27.25f + .25f, 0));
			btmTooth.setFlatColor(new Color(200, 200, 200));
			btmTooth.setShadeMode(eShadeMode.smFlat);

			mFigure.append(torso);
			mFigure.append(leftLeg);
			mFigure.append(rightLeg);
			mFigure.append(leftArm);
			mFigure.append(leftArm2);
			mFigure.append(rightArm);
			mFigure.append(rightArm2);
			mFigure.append(neck);
			mFigure.append(face);
			mFigure.append(leftEye);
			mFigure.append(rightEye);
			mFigure.append(nose);
			mFigure.append(mouth);
			mFigure.append(topTooth);
			mFigure.append(btmTooth);
			#endregion

			mXForm.setPivot(new Vector3(20, 30, 0));
			mXForm.setTranslation(Vector3.Zero);

			mWorldBounds.setCorners(new Vector3(0, 0, 0), new Vector3(36, 36, 0));
		}

		public void updateSimulation()
		{
			//nothing to do here
		}

		public UWB_XFormInfo getModelTransform()
		{
			return mXForm;
		}

		public void setModelTransform(UWB_XFormInfo xFormInfo)
		{
			mXForm = xFormInfo;
		}

		public void getWorldBounds(ref float width, ref float height)
		{
			width = mWorldBounds.width();
			height = mWorldBounds.height();
		}

		public void setupZoom()
		{
			prevSmallX = redBox.Width;
			prevSmallY = redBox.Height;
		}
		public void setZoom(float zoom)
		{
			Vector3 boxCenter = redBox.getLocation();
			Vector3 corner1 = new Vector3(boxCenter.X - ((prevSmallX * zoom) / 2f), boxCenter.Y - ((prevSmallX * zoom) / 2f), 0);
			Vector3 corner2 = new Vector3(boxCenter.X + ((prevSmallY * zoom) / 2f), boxCenter.Y + ((prevSmallY * zoom) / 2f), 0);
			redBox.setCorners(corner1, corner2);

			//redBox.moveTo(zoom * redBox.getLocation().X, zoom * redBox.getLocation().Y);

		}

		public void setSmallWH(float width, float height)
		{
			Vector3 boxCenter = redBox.getLocation();
			Vector3 corner1 = new Vector3(boxCenter.X - (width / 2f), boxCenter.Y - (width / 2f), 0);
			Vector3 corner2 = new Vector3(boxCenter.X + (height / 2f), boxCenter.Y + (height / 2f), 0);
		}

		public void toggleZooming()
		{
			_bZooming = !_bZooming;
		}

		public UWB_BoundingBox GetWorldBounds() 
		{
			return mWorldBounds;
		}

		// move outlining box
		public void moveRedbox(float x, float y)
		{
			redBox.moveTo(x, y);
		}

		public UWB_BoundingBox getWorldBounds()
		{
			return mWorldBounds;
		}

		public void computeWorldCoordinates(int windowWidth, int windowHeight, int deviceX, int deviceY)
		{
			wdX = (((float)deviceX) - ((float)windowWidth) / 2) * (mWorldBounds.width() / (float)windowWidth) + mWorldBounds.width() / 2;
			wdY = (((float)deviceY) - ((float)windowHeight) / 2) * (mWorldBounds.height() / (float)windowHeight) + mWorldBounds.height() / 2;
		}

		public void computeWorldCoordinatesSmall(int windowWidth, int windowHeight, int deviceX, int deviceY)
		{
			wdX = (((float)deviceX) - ((float)windowWidth) / 2) * (redBox.Width / (float)windowWidth) + redBox.Width / 2;
			wdY = (((float)deviceY) - ((float)windowHeight) / 2) * (redBox.Height / (float)windowHeight) + redBox.Height / 2;
		}

		public void showPivot(bool show)
		{
			mShowPivot = show;
		}

		public void drawGrid(UWB_DrawHelper drawHelper, UWB_BoundingBox bounds)
		{
			drawHelper.setShadeMode(eShadeMode.smFlat);
			drawHelper.setColor1(Color.Aqua);

			Vector3 minPoint = bounds.getMin();
			Vector3 maxPoint = bounds.getMax();

			float y = minPoint.Y;
			while (y < maxPoint.Y)
			{
				drawHelper.drawLine(new Vector3(minPoint.X, y, 0), new Vector3(maxPoint.X, y, 0));
				y += 4;
			}

			float x = minPoint.X;
			while (x < maxPoint.X)
			{
				drawHelper.drawLine(new Vector3(x, minPoint.Y, 0), new Vector3(x, maxPoint.Y, 0));
				x += 4;
			}
		}

		public string HoverLocation
		{
			get
			{
				if (_hoverLoc == null)
					_hoverLoc = "???";
				return _hoverLoc;
			}
			set
			{
				_hoverLoc = value;
			}
		}
		#region get/set for coordinates

		

		public float originWCSmallX
		{
			get {
				return redBox.getLocation().X;
			}
		}
		public float originWCSmallY
		{
			get
			{
				return redBox.getLocation().Y;
			}
		}
		public float sizeWCSmallX
		{
			get
			{
				return redBox.Width;
			}
		}
		public float sizeWCSmallY
		{
			get
			{
				return redBox.Height;
			}
		}

		public int hardwareX
		{
			get
			{
				return hwX;
			}

			set
			{
				hwX = value;
			}
		}

		public int hardwareY
		{
			get
			{
				return hwY;
			}

			set
			{
				hwY = value;
			}
		}

		public int deviceX
		{
			get
			{
				return dvX;
			}

			set
			{
				dvX = value;
			}
		}

		public int deviceY
		{
			get
			{
				return dvY;
			}

			set
			{
				dvY = value;
			}
		}

		public float worldX
		{
			get { return wdX; }
		}

		public float worldY
		{
			get { return wdY; }
		}
		#endregion

		public void drawModel()
		{
			eLevelofDetail lod = mDrawHelper.getLod();



			// sets transformations for VIEW
			mDrawHelper.initializeModelTransform();
			mDrawHelper.pushModelTransform(); // push to stack

			drawGrid(mDrawHelper, mWorldBounds); // grids



			// 
			mXForm.setupModelStack(mDrawHelper);
			mFigure.draw(lod, mDrawHelper);

			if (mShowPivot)
				mXForm.drawPivot(mDrawHelper, .5f);

			// red box
			redBox.draw(lod, mDrawHelper);

			
			// pop stack
			mDrawHelper.popModelTransform(); 
		}
	}
}

